package com.vclee.fast.integration.power.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vclee.fast.integration.power.mapper.SysGroupUserMapper;
import com.vclee.fast.integration.power.mapper.SysUserMapper;
import com.vclee.fast.integration.power.mapper.SysUserRoleMapper;
import com.vclee.fast.integration.power.model.*;
import com.vclee.fast.integration.power.model.vo.AdmLoginVo;
import com.vclee.fast.integration.power.model.vo.AdmSysUserPageQuery;
import com.vclee.fast.integration.power.model.vo.MenuTree;
import com.vclee.fast.integration.power.model.vo.SysUserPageVo;
import com.vclee.fast.integration.power.service.SysUserService;
import com.vclee.fast.utils.JwtUtils;
import com.vclee.fast.utils.exception.Assert;
import com.vclee.fast.utils.model.Bson;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysUserServiceImpl implements SysUserService {

    private final SysUserMapper sysUserMapper;
    private final SysUserRoleMapper roleMapper;
    private final SysGroupUserMapper groupUserMapper;
    private final SysUserRoleMapper userRoleMapper;

    @Override
    @Transactional
    public void editUser(SysUser sysUser) {
        int count = sysUserMapper.selectCountByMobileOrUnique(sysUser.getId(),sysUser.getUnique(),sysUser.getMobile());
        Assert.claim(count>0,"该账号或手机号已存在");
        if(sysUser.getId()==null){
            sysUserMapper.insert(sysUser);
        }else {
            sysUserMapper.updateById(sysUser);
        }

        if(Assert.notNull(sysUser.getGroups())){
            LambdaQueryWrapper<SysGroupUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysGroupUser::getUserId,sysUser.getId());
            groupUserMapper.delete(wrapper);
            if(!sysUser.getGroups().isEmpty()){
                List<Integer> ids = sysUser.getGroups().stream().map(SysGroup::getId).collect(Collectors.toList());
                groupUserMapper.batchInsert(sysUser.getId(),ids);
            }
        }

        if(Assert.notNull(sysUser.getRoles())){
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId,sysUser.getId());
            userRoleMapper.delete(wrapper);
            if(!sysUser.getRoles().isEmpty()){
                List<Integer> ids = sysUser.getRoles().stream().map(SysUserRole::getId).collect(Collectors.toList());
                userRoleMapper.batchInsert(sysUser.getId(),sysUser.getOrgId(),ids);
            }
        }

    }

    @Override
    public IPage<SysUserPageVo> getAdmSysUserList(AdmSysUserPageQuery query) {
        LambdaQueryWrapper<SysUser> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getOrgId,query.getOrgId());
        wrapper.like(Assert.notBlank(query.getName()),SysUser::getUsername,query.getName());
        IPage<SysUser> page = sysUserMapper.selectPage(new Page<>(query.getPage(),query.getSize()),wrapper);
        IPage<SysUserPageVo> res = new Page<>(query.getPage(),query.getSize());
        res.setTotal(page.getTotal());
        res.setRecords(page.getRecords().stream()
                .map(item -> {
                    SysUserPageVo vo = Bson.toClazz(item,SysUserPageVo.class);
                    vo.setGroups(groupUserMapper.selectListByUserId(vo.getId()));
                    vo.setRoles(userRoleMapper.selectListByUserId(vo.getId()));
                    return vo;
                })
                .collect(Collectors.toList()));
        return res;
    }

    @Override
    public AdmLoginVo adminLogin(String unique, String password,int flag) {
        LambdaQueryWrapper<SysUser> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUnique,unique);
        SysUser user = sysUserMapper.selectOne(wrapper);
        Assert.isNull(user,"用户不存在");
        Assert.claim(!user.getPassword().equals(password),"密码错误");
        Assert.claim(user.getStatus()==1,401,"用户被冻结");
        AdmLoginVo vo = new AdmLoginVo();
        vo.setUser(user);
        vo.setToken(JwtUtils.updateAccessToken(user.getId()));
        Assert.claim(flag==1&&(user.getOrgId()==null||user.getOrgId()!=0),"账号无权限");
        Assert.claim(flag==0&&(user.getOrgId()==null||user.getOrgId()==0),"账号无权限");
        return vo;
    }

    @Override
    public List<SysUserRole> findUserRoleList(Integer userId, Integer flag) {
//        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(Assert.notNull(userId),SysUserRole::getUserId,userId);
//        wrapper.eq(Assert.notNull(orgId),SysUserRole::getOrgId,orgId);
        return roleMapper.selectMixList(userId,flag);
    }

    @Override
    @Transactional
    public void addUserRole(Integer userId, List<Integer> roleIds, Integer flag, Integer orgId) {
        if(flag == 0){
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId,userId);
            if(orgId!=null){
                wrapper.eq(SysUserRole::getOrgId,orgId);
            }else{
                wrapper.isNull(SysUserRole::getOrgId);
            }
            roleMapper.delete(wrapper);
        }
        if(roleIds!=null && !roleIds.isEmpty()){
            for (Integer roleId : roleIds) {
                SysUserRole role = new SysUserRole();
                role.setRoleId(roleId);
                role.setUserId(userId);
                role.setOrgId(orgId);
                roleMapper.insert(role);
            }
        }
    }

    @Override
    public List<MenuTree> findUserMenuList(Integer userId) {
        List<SysMenu> list = sysUserMapper.findUserAllMenu(userId);
        List<SysMenu> groupList = sysUserMapper.findGroupAllMenu(userId);
        if(groupList!=null){
            list.addAll(groupList);
            list = list.stream().distinct().collect(Collectors.toList());
        }
//        List<MenuTree> menuList =SysMenuServiceImpl.getMenuTree(list);
//        if (menuList.isEmpty()){
//            MenuTree menuTree = new MenuTree();
//            menuTree.setPath("/home");
//            menuTree.setId(44);
//            menuTree.setTitle("首页");
//            menuTree.setIcon("home");
////            menuTree.setChildren(getChildren(menuTree, list));
//            menuList.add(menuTree);
//        }
        return SysMenuServiceImpl.getMenuTree(list);
    }


    public static List<MenuTree> getChildren(MenuTree tree, List<SysMenu> list) {
        List<MenuTree> treeList = new ArrayList<>();
        for (SysMenu vo : list) {
            if (vo.getParentId() != null && vo.getParentId().equals(tree.getId())) {
                MenuTree menuTree = new MenuTree();
                menuTree.setId(vo.getId());
                menuTree.setPath(vo.getUrl());
                menuTree.setTitle(vo.getMenuName());
                menuTree.setIcon(vo.getIcon());
                menuTree.setParentId(vo.getParentId());
                menuTree.setUrls(vo.getUrls());
                menuTree.setSortNum(vo.getSortNum());
                menuTree.setIsShow(vo.getIsShow());
                menuTree.setChildren(getChildren(menuTree, list));
                treeList.add(menuTree);
            }

        }
        if(!treeList.isEmpty()){
            treeList.sort(Comparator.comparing(MenuTree::getSortNum));
            Collections.reverse(treeList);
        }
        return treeList;
    }
}
